spec(SERVE-RECIPE-ARGS): a published recipe command must reach model load (#606) - #613
spec(SERVE-RECIPE-ARGS): a published recipe command must reach model load (#606)#613localai-bot wants to merge 2 commits into
Conversation
…load (#606) FOLLOWING_AGENTS_PROTOCOL vllm-serve rejects any argument it does not recognise (server_main.cpp:440). That is the right default, and it is why two flags that mean nothing to us stop the server before it loads a model: --enable-auto-tool-choice, which 89 of the 157 official vLLM recipes pass, and --trust-remote-code, which 82 pass. We parse tool calls whenever --tool-call-parser resolves, so there is no second gate to open; and we have no Python, so there is no remote code to trust. Both are inert, and both abort -- including for Qwen3.5-27B, which we ship token-exact and gated. The kernels are not what stands between a user and a running server here. The spec is deliberately narrow about what the seam may swallow. An enumerated table, one entry per flag with the reason it is inert; anything unlisted still aborts, because silently accepting --tensor-parallel-size would let a user believe they got tensor parallelism, and that is the failure mode this exists to prevent. Flags inert because we LACK the capability -- TP, EP, --mm-encoder-tp-mode -- are explicitly excluded and keep aborting. So is --language-model-only (#607), which is a real capability gap wearing the same costume. Two things the spec records rather than papers over. cli_args.py:395 makes --enable-auto-tool-choice without --tool-call-parser a TypeError upstream, so inert must not mean unvalidated and the mirrored failure is a named test case. And upstream defaults --tool-call-parser to None where we default it to hermes, so upstream's flag genuinely gates something ours cannot -- pre-existing, out of scope, and called out so the notice text does not overclaim parity. ENGINE_ROWS 152 -> 153 for the new row, with the justification the checker's own comment ledger asks for. No checker semantics change: the row claims no seam, no test and no USAGE entry, because none exists yet. Spec and records only, no product code touched. scripts/agent-preflight.sh --staged: exit 0. Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
…#606) FOLLOWING_AGENTS_PROTOCOL check-pr-size.py classifies scripts/check-agent-record.py as a governance checker and requires companion evidence in tests/scripts/test_agent_record.py for any change to it -- including the ENGINE_ROWS 152 -> 153 bump that carries the new row. That rule is right: without it, a bump made to silence a broken count looks identical to a bump made for a real row. Mirrors test_windows_release_row_is_inside_the_engine_ratchet, added for the same reason when the constant last moved. Two mutations were run in the worktree and BOTH were caught, but neither by this assertion: deleting the row is caught by the count ratchet in setUpClass (152 engine rows; expected 153), and renaming it while keeping the count is caught by the claim cross-check (owner CLAIM-SERVE-RECIPE-ARGS does not claim active row SERVE-RECIPE-ARGZ). So this test is a third pin on an invariant two existing guards already defend, not an independent guard -- the same is true of the Windows test it mirrors, and it is worth saying plainly rather than reporting a mutation proof that was actually someone else's assertion firing. The tree was restored byte-for-byte after each mutation; git diff HEAD over .agents/ is empty. python3 -m unittest tests.scripts.test_agent_record: 50 tests, OK. Following-Agents-Protocol: true AI-Assisted: true Assisted-by: AGENT:claude-opus-5 [Claude Code]
|
Tracked by #503 and #603. Recording the attribution so a reviewer does not
Neither this PR nor #616 touches Not claimed as green, and not waived: the jobs are genuinely failing, the cause is |
|
Correction to my earlier comment: the specific cause is #584, not #503/#603. I attributed the red Windows lanes to #503 / #603 — a compile break (POSIX The observed failure is a runtime crash, not a compile error: What does not change: the failure is still not attributable to this PR.
Recording the correction rather than editing the original comment, so the wrong |
|
Closing as superseded by #624, which contains this branch's spec commit Verified rather than assumed:
The one thing this branch had that #624 initially lacked was that test commit,
Closed per AGENTS.md: obsolete PRs are closed with the reason recorded, never left |
Closes the spec-before-code gate for #606. Adds
.agents/specs/serve-recipe-args.md,the new
SERVE-RECIPE-ARGSrow atSPIKE, and its claim file.The defect
vllm-serverejects any argument it does not recognise(
src/vllm/entrypoints/openai/server_main.cpp:440). That is the right default —and it is why two flags that mean nothing to us stop the server before it loads a
model:
--enable-auto-tool-choice--tool-call-parserresolves--trust-remote-codeThe reproducer is a recipe's own copy-paste block, for a model we ship token-exact
and gated:
vllm serve Qwen/Qwen3.5-27B-FP8 --enable-auto-tool-choice --tool-call-parser qwen3_coder # ^ server: unknown argument '--enable-auto-tool-choice'What the spec commits to
An enumerated accepted-and-inert table, one entry per flag carrying the reason
it is inert — not a catch-all. Three rules:
--tensor-parallel-sizewould let a user believe they got TP. That the table is enumerated is the whole
value of the seam.
than inferring it worked.
cli_args.py:395makes--enable-auto-tool-choicewithout a parser aTypeErrorupstream. Inert isnot unvalidated.
Explicitly excluded: flags inert because we lack the capability (TP, EP,
--mm-encoder-tp-mode) keep aborting, and--language-model-only(#607) is a realcapability gap that must not be quietly absorbed here.
Recorded, not papered over
Upstream defaults
--tool-call-parsertoNone; we default it tohermes(
docs/USAGE.md:878). Upstream's flag therefore gates something ours cannot. Thatis pre-existing and out of scope, and the spec says so, so the notice text cannot
overclaim parity.
Tests named in the spec
RED-first, with the load-bearing case being "an unlisted unknown flag still
aborts" — a mutation turning the table into a catch-all must turn it RED, proven
in a scratch copy with the tree restored byte-for-byte.
Row accounting
ENGINE_ROWS152 → 153 with the justificationcheck-agent-record.py's owncomment ledger asks for. No checker semantics change: the row claims no seam, no
test, no
docs/USAGE.mdentry — none exists yet.Spec and records only, no product code.
scripts/agent-preflight.sh --staged: exit 0.🤖 Generated with Claude Code